local desc_role = [[
  # 氯师杀身份模式简介
  ___
  此模式基于萌战evolution身份局规则修改
  
  （一）身份改动及身份“明置”相关
  
  1.主公
  
  若游戏人数大于5，且主公有主公技，游戏开始时，主公可以失去主公技，获得一项“国策”。
  
  国策及其效果分别为：
  
  固略：出牌阶段开始时，你可观看一名角色的身份牌和手牌；回合技，当你成为非先驱角色使用【杀】的目标后，你摸一张牌。
  
  尊威：出牌阶段开始时，你可摸一张牌，然后明置一张手牌；回合技，其他非先驱角色于此轮使用或打出与此牌花色相同的牌时，你可令其弃置一张牌。
  
  崇武：出牌阶段开始时，你可摸一张牌，与一名其他角色拼点；若你赢，你于此回合获得效果：回合技，当你使用牌对非先驱角色造成伤害时，你可令此伤害+1。
  
 2.主公身份牌不可被暗置。一名角色的回合开始时，若其身份不为主公，其可明置身份牌，然后触发以下效果：
  
 （1）忠臣
  你弃置场上的一张牌，然后获得“支援”：出牌阶段结束时，你可交给己方角色一张暗置牌并明置。
  
 （2）反贼
  若你为首个明置的角色，你获得一枚先驱标记并成为贼首（回合开始时，你可弃一枚先驱标记，将手牌数补至四张），否则你可令一名手牌数不大于你的其他己方角色摸一张牌。
  
  （3）内奸
  内奸的胜利条件改为主公死亡时无反贼存活。
  
  若游戏人数大于5，内奸明置身份牌后抽取两条命运线（大于7为三条）并选择一条：
  
  争师：一名角色的回合结束后，若贼首已死亡，你成为贼首（不获得先驱标记）。
  
  夺天：其他角色死亡时，若你杀死过两名角色，你与主公交换身份牌，回复所有体力，获得其“国策”。
  
  拯庙：一名角色的回合结束后，若忠臣均死亡且有反贼存活，你将身份变为忠臣。

  申野：一名角色的回合结束后，若场上角色的手牌形成公差大于0的等差数列，你获胜。

  僭炳：回合开始时，若场上身份数等于角色数，你将身份变为主公并获得一项国策，然后其他角色身份变为反贼，你摸牌阶段改为摸X张牌，手牌上限+X（X为场上角色数）。

  困图：觉醒技，准备阶段，若你已受伤，你增加1点体力上限，回复体力至体力上限，摸等量的牌，获得所有国策。

  玄隐：一名角色的回合结束后，若非主公角色的体力值均不大于2，你减1点体力上限，然后你变为平民。

  3.身份奖惩
  主公击杀忠臣不再弃置所有牌，改为失去国策。
  击杀反贼的奖励改为摸X张牌。（X为存活反贼数+1，击杀贼首仍固定摸3）
  内奸击杀忠臣后增加1点体力上限并回复1点体力。
]]


local role_mode = fk.CreateGameMode{
  name = "lvshi_role_mode", -- just to let it at the top of list
  minPlayer = 2,
  maxPlayer = 8,
  main_mode = "role_mode",
  rule = "#lvshi_rule&",
  logic = function()
    local l = GameLogic:subclass("lvshi_role_mode_logic")
    function l:run()
      self.room.settings._game.enableDeputy = false
      GameLogic.run(self)
    end
    function l:chooseGenerals()
      local room = self.room---@type Room
      local generalNum = room:getSettings('generalNum')
      local lord = room:getLord()
      if not lord then
        local temp = room.players[1]
        temp.role = "lord"
        lord = temp
      end
      room:setCurrent(lord)

      local lord_general_num = 3
      local lord_generals = table.connect(room:findGenerals(function(g)
        return table.contains(Fk.lords, g)
      end, lord_general_num), room:getNGenerals(generalNum))
      if #lord_generals < generalNum then
        room:sendLog{ type = "#NoGeneralDraw", toast = true }
        room:gameOver("")
      end

      local lord_general = room:askToChooseGeneral(lord, {generals = lord_generals, n = 1})---@type string
      room:returnToGeneralPile(lord_generals)
      room:findGeneral(lord_general)

      room:prepareGeneral(lord, lord_general, "", true)
      room:askToChooseKingdom({lord})
      room:broadcastProperty(lord, "kingdom")
      room:broadcastProperty(lord, "general")

      local canAttachSkill = function(player, skillName)
        local skill = Fk.skills[skillName]
        if not skill then
          fk.qCritical("Skill: "..skillName.." doesn't exist!")
          return false
        end
        if skill:hasTag(Skill.Lord) and not (player.role == "lord" and player.role_shown and room:isGameMode("lvshi_role_mode")) then
          return false
        end

        if skill:hasTag(Skill.AttachedKingdom) and not table.contains(skill:getSkeleton().attached_kingdom, player.kingdom) then
          return false
        end

        return true
      end

      local lord_skills = {}
      for _, s in ipairs(Fk.generals[lord.general].skills) do
        if canAttachSkill(lord, s.name) then
          table.insertIfNeed(lord_skills, s.name)
        end
      end
      for _, sname in ipairs(Fk.generals[lord.general].other_skills) do
        if canAttachSkill(lord, sname) then
          table.insertIfNeed(lord_skills, sname)
        end
      end
      for _, skill in ipairs(lord_skills) do
        room:doBroadcastNotify("AddSkill", {
          lord.id,
          skill
        })
      end
      
      local nonlord = room:getOtherPlayers(lord, true)
      local generals = table.random(room.general_pile, #nonlord * generalNum)
      if #generals < #nonlord * generalNum then
        room:sendLog{ type = "#NoGeneralDraw", toast = true }
        room:gameOver("")
      end

      local req = Request:new(nonlord, "AskForGeneral")
      for i, p in ipairs(nonlord) do
        local arg = table.slice(generals, (i - 1) * generalNum + 1, i * generalNum + 1)
        req:setData(p, { arg, 1 })
        req:setDefaultReply(p, table.random(arg, 1))
      end

      for _, p in ipairs(nonlord) do
        local result = req:getResult(p)
        local general = result[1]
        room:findGeneral(general)
        room:prepareGeneral(p, general, "")
      end
      room:askToChooseKingdom(nonlord)
    end

    return l
  end,
  is_counted = function(self, room)
    return #room.players == 6 or #room.players == 8 --i龙
  end,
  surrender_func = Fk.game_modes["aaa_role_mode"].surrenderFunc,
  reward_punish = function (self, victim, killer)
    local room = victim.room
    if not killer then return end
    if killer.role == 'renegade' and victim.role == 'loyalist' then
      room:changeMaxHp(killer, 1)
      if not killer.dead and killer:isWounded() then
        room:recover{
          num = 1,
          who = killer,
          recoverBy = killer,
          skillName = "game_rule",
        }
      end
    end
    if killer.role == 'lord' and victim.role == 'loyalist' and room:getBanner() then
      local lvshi__policy = room:getBanner("@[:]lvshi__policy")
      if lvshi__policy and lvshi__policy ~= "" then
        room:handleAddLoseSkills(killer, "-" .. lvshi__policy, nil, false)
        room:setBanner("@[:]lvshi__policy", "")
      end
    end
    if victim.role == "rebel" or victim.role == "rebel_chief" then
      local n = #table.filter(room.alive_players, function (p)
        return p.role == "rebel" or p.role == "rebel_chief"
      end) + 1
      if victim.role == "rebel_chief" then
        n = 3
      end
      if n > 0 then
        killer:drawCards(n, "kill")
      end
    elseif victim.role == "civilian" then
      killer:drawCards(2, "kill")
    end
  end,
  winner_getter = function(self, victim)
    if not victim.surrendered and victim.rest > 0 then
      return ""
    end
    local room = victim.room
    local winner = ""
    local alive = table.filter(room.players, function(p)
      return not p.surrendered and not (p.dead and p.rest == 0) and p.role ~= "civilian"
    end)
    if victim.role == "lord" then
      if not table.find(room.alive_players, function (p) return p.role == "rebel" or p.role == "rebel_chief" end) then
        winner = "renegade"
      else
        winner = "rebel+rebel_chief"
      end
    elseif victim.role ~= "loyalist" then
      local lord_win = true
      for _, p in ipairs(alive) do
        if p.role == "rebel" or p.role == "rebel_chief" or p.role == "renegade" then
          lord_win = false
          break
        end
      end
      if lord_win then
        winner = "lord+loyalist"
      end
    end
    if winner ~= "" and table.find(room.alive_players, function (p) return p.role == "civilian" end) then
      winner = winner.. "+civilian"
    end
    return winner
  end
}

Fk:loadTranslationTable{
  ["lvshi_role_mode"] = "氯师身份模式",
  [":lvshi_role_mode"] = desc_role,
  ["#lvshi_role_rule"] = "氯师身份规则",
  ["#lvshi_rule&"] = "氯师身份规则",
}

return role_mode
